﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.Xna.Framework;
using System.Collections;
using Algorithms;
using JMBucknall.Containers;

namespace WindowsGame4
{
    class GameInfo
    {
        static private GameInfo gameInfo = null;
        private World world;
        int countObjects;
        private Dictionary<String, Dictionary<String, Object>> objects;
        public GameInfoLoader gameInfoLoader;
        AIInterface aiInterface;
        int level;
        public Dictionary<String, Model> models;
        int maxVision;
        int minMission;

        private GameInfo()
        {
            world = null;
            countObjects = 0;
            level = 1;
            gameInfoLoader = GameInfoLoader.getInstance();
            aiInterface = AIInterface.getInstance();
            maxVision = 13;
            minMission = 1;
            objects = new Dictionary<string, Dictionary<string, Object>>();
            objects.Add("player", new Dictionary<string, Object>());
            objects.Add("colision", new Dictionary<string, Object>());
            objects.Add("enemy", new Dictionary<string, Object>());
            objects.Add("bomb", new Dictionary<string, Object>());
            objects.Add("projectile", new Dictionary<string, Object>());
            objects.Add("explosion", new Dictionary<string, Object>());
            objects.Add("items", new Dictionary<string, Object>());
            objects.Add("wall", new Dictionary<string, Object>());
        }

        public String generateId()
        {
            // Generate id
            return Convert.ToString(countObjects++);
        }

        public Player registerPlayer(Position2D position, Model model)
        {
            Player obj = new Player(generateId(), position, model);
            obj.IdAnimation = model.DefaultAnimaton;
            obj.Colision = new Rectangle(5, -35, 50, 30);
            obj.HorizontalColision = new Rectangle(16, 40, 30, 15);
            obj.VerticalColision = new Rectangle(25, 30, 10, 28);
            objects["player"].Add(obj.Id, obj);
            return obj;

        }

        public Enemy registerEnemy(Position2D position, Model model)
        {
            Enemy obj = new Enemy(generateId(), position, model);
            obj.IdAnimation = model.DefaultAnimaton;
            //obj.Colision = new Rectangle(0, -40, 64, 100);
            obj.Colision = new Rectangle(5, -30, 50, 60);
            objects["enemy"].Add(obj.Id, obj);
            return obj;
        }

        public Colision registerColision(Position2D position, Model model, Boolean destroyable, int life)
        {
            Colision obj = new Colision(generateId(),position,model,destroyable,life);
            if(model != null)
            obj.IdAnimation = model.DefaultAnimaton;
            objects["colision"].Add(obj.Id,obj);
            return obj;
        }

        public Wall registerWall(Position2D position, Model model)
        {
            Wall obj = new Wall(generateId(), position, model);
            obj.IdAnimation = model.DefaultAnimaton;
            objects["wall"].Add(obj.Id, obj);
            return obj;
        }

        public Projectile registerProjectile(Position2D position, Model model)
        {
            Projectile obj = new Projectile(generateId(), position, model);

            obj.HorizontalColision = new Rectangle(10, 22, 55, 16);
            obj.VerticalColision = new Rectangle(26, 10, 10, 48);
            obj.IdAnimation = model.DefaultAnimaton;
            objects["projectile"].Add(obj.Id, obj);
            return obj;
        }

        public Explosion registerExplosion(Position2D position, Model model, String idEmissor)
        {
            Explosion obj = new Explosion(generateId(), position, model, idEmissor);
            obj.IdAnimation = model.DefaultAnimaton;
            obj.Colision = new Rectangle(0, 0, 64, 64);
            objects["explosion"].Add(obj.Id, obj);
            return obj;
        }

        public Bomb registerBomb(Position2D position, Model model)
        {
            Bomb obj = new Bomb(generateId(), position, model);
            obj.IdAnimation = model.DefaultAnimaton;
            objects["bomb"].Add(obj.Id, obj);
            return obj;
        }

        public Item registerItem(Position2D position, Model model)
        {
            Item obj = new Item(generateId(), position, model);
            obj.IdAnimation = model.DefaultAnimaton;
            objects["items"].Add(obj.Id, obj);
            return obj;
        }

        public ArrayList getCharacters()
        {
            ArrayList characters = new ArrayList();

            Dictionary<String, Object> aux = objects["player"];
            foreach (KeyValuePair<String, Object> item in aux)
            {
                Object obj = item.Value;
                characters.Add(obj);
            }

            aux = objects["enemy"];
            foreach (KeyValuePair<String, Object> item in aux)
            {
                Object obj = item.Value;
                characters.Add(obj);
            }

            return characters;
        }

        public void createItem(int row, int column)
        {
            Cell cell = world.get(row, column);
  
            Random r = new Random(DateTime.Now.Millisecond);
            int number = r.Next(0, 3);
            switch (number)
            {
                case 0:
                    {
                        // Level
                        Object o = registerItem(new Position2D(cell.getRealX(), cell.getRealY()), models["level"]);
                        o.Level += 1;
                        break;
                    }
                case 1:
                    {
                        // Gun ammo
                        Object o = registerItem(new Position2D(cell.getRealX(), cell.getRealY()), models["gunAmmo"]);
                        o.GunAmmo += 10;
                        break;
                    }
                case 2:
                    {
                        // Bomb ammo
                        Object o = registerItem(new Position2D(cell.getRealX(), cell.getRealY()), models["bombAmmo"]);
                        o.BombAmmo += 10;
                        break;
                    }
            }
        }

        public void createRandomStar(int num)
        {
            Random r = new Random(DateTime.Now.Millisecond);
            for (int i = 0; i < num; i++)
            {
                // Get empty cell
                Cell cell = null;
                while (cell == null)
                {
                    int row = r.Next(0, world.Rows);
                    int column = r.Next(0, world.Columns);
                    if (world.get(row, column).Obj == null)
                        cell = world.get(row, column);
                }
                Object o = registerItem(new Position2D(cell.getRealX(), cell.getRealY()), models["level"]);
                o.Level += 1;
            }
        }

        public void createRandomItem()
        {
            Random r = new Random(DateTime.Now.Millisecond);
            // Get empty cell
            Cell cell = null;
            while (cell == null)
            {
                int row = r.Next(0, world.Rows);
                int column = r.Next(0, world.Columns);
                if (world.get(row, column).Obj == null)
                    cell = world.get(row, column);
            }
            createItem(cell.Row, cell.Column);
        }

        public void updateGLX()
        {
            foreach (KeyValuePair<String, Dictionary<String, Object>> aux in objects)
            {
                foreach (KeyValuePair<String, Object> i in aux.Value)
                {
                    Object obj = i.Value;
                    obj.updateGLX();
                }
            }
        }

        public Object getObject(String id)
        {
            foreach (KeyValuePair<String, Dictionary<String, Object>> aux in objects)
            {
                foreach (KeyValuePair<String, Object> i in aux.Value)
                {
                    Object obj = i.Value;
                    if (obj.Id == id)
                        return obj;
                }
            }
            return null;
        }

        public Dictionary<String, Model> loadModels()
        {
            Dictionary<String, Model> models = new Dictionary<string, Model>();

            StreamReader streamReader = new StreamReader("Content\\models.txt");

            String line = streamReader.ReadLine();
            while (line != null)
            {
                String idModel = line.Split(';')[0];
                Model model = new Model(idModel);

                line = streamReader.ReadLine();
            }

            return models;
        }

        public void removeObject(String id, Object.TypeObject type)
        {
            foreach (KeyValuePair<String, Dictionary<String, Object>> aux in objects)
            {
                aux.Value.Remove(id);
                aiInterface.deleteObject(id);
                // Check if is in the world
                for (int i = 0; i < world.Rows; i++)
                {
                    for (int j = 0; j < world.Columns; j++)
                    {
                        Cell cell = world.get(i, j);
                        if (cell.Obj != null && cell.Obj.Id == id)
                            cell.Obj = null;
                    }
                }
            }      
        }

        public void draw(String type)
        {
            Dictionary<String, Object> aux = objects[type];
            foreach (KeyValuePair<String, Object> item in aux)
            {
                Object obj = item.Value;
                if (obj.Visible == true) // && obj.Type == Object.TypeObject.player)
                    obj.draw();
            }
        }

        public void draw()
        {


            draw("explosion");

            PriorityQueue orderObjects = new PriorityQueue();
            /*
            orderObjects.Enqueue("1", new ReversePriority(2));
            orderObjects.Enqueue("2", new ReversePriority(5));
            orderObjects.Enqueue("3", new ReversePriority(1));*/

            /*
            Dictionary<String, Object> aux = objects["explosion"];
            foreach (KeyValuePair<String, Object> item in aux)
            {
                Object obj = item.Value;

                    orderObjects.Enqueue(obj, new ReversePriority(obj.Position.Y));

            }*/

            Dictionary<String, Object>  aux = objects["wall"];
            foreach (KeyValuePair<String, Object> item in aux)
            {
                Object obj = item.Value;
                if (obj.Height > 64)
                {
                    orderObjects.Enqueue(obj, new ReversePriority(obj.Position.Y + 64));
                    //Console.ReadKey();
                }
                else
                    orderObjects.Enqueue(obj, new ReversePriority(obj.Position.Y));
    
            }

            aux = objects["bomb"];
            foreach (KeyValuePair<String, Object> item in aux)
            {
                Object obj = item.Value;
                if (obj.Height > 64)
                {
                    orderObjects.Enqueue(obj, new ReversePriority(obj.Position.Y + 64));
                    //Console.ReadKey();
                }
                else
                    orderObjects.Enqueue(obj, new ReversePriority(obj.Position.Y));
        
            }
            /*
            aux = objects["projectile"];
            foreach (KeyValuePair<String, Object> item in aux)
            {
                Object obj = item.Value;
                if (obj.Height > 64)
                {
                    orderObjects.Enqueue(obj, new ReversePriority(obj.Position.Y + 64));
                    //Console.ReadKey();
                }
                else
                    orderObjects.Enqueue(obj, new ReversePriority(obj.Position.Y));
                System.Console.WriteLine("wall: " + obj.Position.X + " " + obj.Position.Y);
            }
             */
            /*
            aux = objects["items"];
            foreach (KeyValuePair<String, Object> item in aux)
            {
                Object obj = item.Value;
                if (obj.Height > 64)
                {
                    orderObjects.Enqueue(obj, new ReversePriority(obj.Position.Y + 64));
                    //Console.ReadKey();
                }
                else
                    orderObjects.Enqueue(obj, new ReversePriority(obj.Position.Y));
                System.Console.WriteLine("wall: " + obj.Position.X + " " + obj.Position.Y);
            }  
             */
            ArrayList characters = getCharacters();

            for(int i = 0; i < characters.Count; i++)
            {
                Object obj = (Object)characters[i];
                orderObjects.Enqueue(obj, new ReversePriority(obj.Position.Y));

            }

            while( orderObjects.Count > 0)
            {
                Object obj = (Object)orderObjects.Dequeue();
                obj.draw();
            }

            //System.Console.ReadKey();

            /*
            Dictionary<String, Object> aux = objects["wall"];
            foreach (KeyValuePair<String, Object> item in aux)
            {
                Object obj = item.Value;
                if (obj.Visible == true)
                {
                    Object player = getPlayer("joris");
                    System.Console.WriteLine("wall: " + player.Position.X + " " + player.Position.Y);
                    System.Console.WriteLine("player: " + obj.Position.X + " " + obj.Position.Y);
                    if(obj.Position.Y < player.Position.Y)
                    obj.draw();
                }
            }
            */

            //draw("colision");
            //draw("enemy");
            //draw("player");
            draw("items");
            //draw("bomb");
            draw("projectile");
            
            /*
            aux = objects["wall"];

            foreach (KeyValuePair<String, Object> item in aux)
            {
                Object obj = item.Value;
                if (obj.Visible == true)
                {
                    Object player = getPlayer("joris");
                    //System.Console.WriteLine("player: " + player.Position.X + " " + player.Position.Y);
                    //System.Console.WriteLine("wall: " + obj.Position.X + " " + obj.Position.Y);
                    if (obj.Position.Y >= player.Position.Y || obj.Depth == 1)
                        obj.draw();

                }
            }*/
            
            
        }

        public void attackGun(Object obj)
        {
            // Check if the object can attack
            if (obj.Attack == true)
            {
                // Check ammo
                if (obj.GunAmmo > 0)
                {
                    // Create projectile
                    createProjectil(obj);
                    // Decrement ammo
                    obj.GunAmmo--;
                    // Disable attack
                    obj.Attack = false;
                    // Create a message to enable attack 
                    obj.ReloadTime = 80;
                    //EventEmitter.getInstance().registerMessage(9000000 - obj.Level * 500000, obj.Id, obj.Id, Message.MessageType.msg_newShoot);
                }
            }
        }

        public void attackBomb(Object obj)
        {
            // Check if the object can attack
            if (obj.Attack == true)
            {
                // Check ammo
                if (obj.BombAmmo > 0)
                {
                    // Create projectile
                    createBomb(obj);
                    // Decrement ammo
                    obj.BombAmmo--;
                    // Disable attack
                    obj.Attack = false;
                    // Create a message to enable attack 
                    obj.ReloadTime = 80;
                    //EventEmitter.getInstance().registerMessage(9000000 - obj.Level * 500000, obj.Id, obj.Id, Message.MessageType.msg_newShoot);
                }
            }
        }

        public void createProjectil(Object emisor)
        {
            Projectile o = (Projectile)gameInfo.registerProjectile(new Position2D(emisor.Position.X
                                    , emisor.Position.Y-64), models["projectile"]);
            o.IdEmissor = emisor.Id;
            int x = emisor.Position.X;
            int y = emisor.Position.Y;
            o.Team = emisor.Team;
            switch (emisor.Direction.getDirection())
            {
                case "left":
                    {
                        x -= o.Distance;
                        o.changeAnimation("left");
                        break;
                    }
                case "right":
                    {
                        x += o.Distance;
                        o.changeAnimation("right");
                        break;
                    }
                case "up":
                    {
                        y -= o.Distance;
                        o.changeAnimation("back");
                        break;
                    }
                case "down":
                    {
                        y += o.Distance;
                        o.changeAnimation("front");
                        break;
                    }
                default:
                    {
                        y += o.Distance;
                        break;
                    }
            }
            o.Direction = new Direction2D(emisor.Direction.X,emisor.Direction.Y);
            o.Movement = new Position2D(x, y);
            // Register AIObject
            //System.Console.WriteLine("create projectile: " + emisor.Id + emisor.Name);
            aiInterface.registerObject(o.Id, AIObject.TypeAIObject.AIProjectile);
            if (Game1.enableMusic)
                Game1.projectileSound.Play();
        }

        public void createBomb(Object emitter)
        {
            Bomb o = (Bomb)gameInfo.registerBomb(new Position2D(emitter.Position.X, emitter.Position.Y), models["bomb"]);
            // Set emitter
            o.IdEmitter = emitter.Id;
            // Set distance
            o.Distance = emitter.Level;
            // Register AIObject
            aiInterface.registerObject(o.Id, AIObject.TypeAIObject.AIBomb);
        }

        public ArrayList getNearbyCells(int row, int column, int distance)
        {
            ArrayList cells = new ArrayList();
            cells.Add(World.get(row,column));
            for (int i = 1; i <= distance; i++)
            {
                if(row-i >= 0)
                    cells.Add(World.get(row-i,column));
                if(row+i < World.Rows)
                    cells.Add(World.get(row+i,column));
                if(column-i >= 0)
                    cells.Add(World.get(row,column-i));
                if(column+i < World.Columns)
                    cells.Add(World.get(row,column+i));
            }
            return cells;
        }

        public Boolean createExplosion(int x, int y, String direction, int distance, int maxDistance, String idEmissor)
        {
            Boolean stop = false;

            // Check colision
            ArrayList type = new ArrayList();
            type.Add("colision");
            ArrayList ignore = new ArrayList();
            Object bomb = gameInfo.getObject(idEmissor);
            Object o = gameInfo.registerExplosion(new Position2D(x, y), models["explosion_"+bomb.Team], idEmissor);

            Object victim = gameInfo.checkColision(o, "bomb", ignore);
            if (victim != null)
            {
                //System.Console.WriteLine("Colision wih " + victim.Id);
                
                if (victim.Type == Object.TypeObject.colision)
                {
                    
                    Colision colision = (Colision)victim;
                    if (colision.Life == 0)
                    {
                        Explosion ex = (Explosion)o;
                       // ex.Disable = true;
                       // System.Console.WriteLine(direction + "," + distance + "," + maxDistance);
                       // System.Console.ReadKey();
                        // Remove
                        //gameInfo.removeObject(o.Id);
                    }
                    //else
                    //{
                        // Not remove
                        o.changeAnimation("close_" + direction);
                        aiInterface.registerObject(o.Id, AIObject.TypeAIObject.AIExplosion);
                    //}
                    stop = true;
                }
            }
            else
            {
                if (maxDistance == distance + 1)
                {
                    o.changeAnimation("close_"+direction);
                    stop = true;
                }
                else
                    o.changeAnimation(direction);
                aiInterface.registerObject(o.Id, AIObject.TypeAIObject.AIExplosion);
            }

            return stop;
        }

        public void createExplosions(int posX, int posY, int distance, String idEmisor)
        {
            Object bomb = gameInfo.getObject(idEmisor);
            Object o = gameInfo.registerExplosion(new Position2D(posX, posY), models["explosion_" + bomb.Team], idEmisor);
            o.changeAnimation("cross");
            // Register AIObject
            aiInterface.registerObject(o.Id, AIObject.TypeAIObject.AIExplosion);

            // ADD down explosions
            for (int i = 0; i < distance; i++)
            {
                int x = posX;
                int y = posY+(i+1)*64;
                if (createExplosion(x, y, "down", i, distance, idEmisor) == true)
                    break;
            }
            // ADD up explosions
            for (int i = 0; i < distance; i++)
            {
                int x = posX;
                int y = posY - (i + 1) * 64;
                if (createExplosion(x, y, "up", i, distance, idEmisor) == true)
                    break;
            }
            // ADD left explosions
            for (int i = 0; i < distance; i++)
            {
                int x = posX- (i + 1) * 64;;
                int y = posY;
                if (createExplosion(x, y, "left", i, distance, idEmisor) == true)
                    break;
            }
            // ADD right explosions
            for (int i = 0; i < distance; i++)
            {
                int x = posX + (i + 1) * 64; ;
                int y = posY;
                if (createExplosion(x, y, "right", i, distance, idEmisor) == true)
                    break;
            }                       
        }

        public void drawCellVision(int row, int column)
        {
            Game1.spriteBatch.Begin();
            Game1.spriteBatch.Draw(Game1.textVisionCell, new Rectangle(column * world.Size, row * world.Size, Game1.textVisionCell.Bounds.Width, Game1.textVisionCell.Bounds.Height), Color.White);
            Game1.spriteBatch.End();
        }

        public void drawStadistics(Object obj, int posX)
        {
            
            int posY = 670;
            Game1.spriteBatch.Begin();
            if (obj.Team == "red")
                Game1.spriteBatch.Draw(Game1.textStadisticsRed, new Rectangle(posX, posY, Game1.textStadisticsRed.Bounds.Width, Game1.textStadisticsRed.Bounds.Height), Color.White);
            else
                Game1.spriteBatch.Draw(Game1.textStadisticsGreen, new Rectangle(posX, posY, Game1.textStadisticsGreen.Bounds.Width, Game1.textStadisticsGreen.Bounds.Height), Color.White);
            posY += 2;
            Game1.spriteBatch.DrawString(Game1.font, obj.Name, new Vector2(posX + 70, posY), Color.Black);
            posY += 32;
            Game1.spriteBatch.DrawString(Game1.font, "" + obj.GunAmmo, new Vector2(posX + 105, posY), Color.Black);
            Game1.spriteBatch.DrawString(Game1.font, "" + obj.BombAmmo, new Vector2(posX + 170, posY), Color.Black);
            posY += 28;
            Game1.spriteBatch.DrawString(Game1.font, "" + obj.Kills, new Vector2(posX + 75, posY), Color.Black);
            //Game1.spriteBatch.DrawString(Game1.font, "" + player.BombAmmo, new Vector2(380 + 190, 713), Color.Black);
            Game1.spriteBatch.End();
            
        }

        public void drawPlayerAmmo()
        {
            int width = 1024;

            ArrayList characters = getCharacters();
            int marginX = width - (characters.Count * (Game1.textStadisticsRed.Bounds.Width + 20));
            int posX = marginX/2;
            for (int i = 0; i < characters.Count; i++)
            {
                Object obj = (Object)characters[i];
                if (obj.Team == "green")
                {
                    drawStadistics(obj,posX);
                    posX += Game1.textStadisticsRed.Bounds.Width + 20;
                }
            }
            for (int i = 0; i < characters.Count; i++)
            {
                Object obj = (Object)characters[i];
                if (obj.Team == "red")
                {
                    drawStadistics(obj,posX);
                    posX += Game1.textStadisticsRed.Bounds.Width + 20;
                }
            }
            /*
            Game1.spriteBatch.Begin();
            Game1.spriteBatch.Draw(Game1.textAmmoMenu, new Rectangle(380, 700, Game1.textAmmoMenu.Bounds.Width, Game1.textAmmoMenu.Bounds.Height), Color.White);
            Game1.spriteBatch.DrawString(Game1.font, "" + player.GunAmmo, new Vector2(380 + 80, 713), Color.Black);
            Game1.spriteBatch.DrawString(Game1.font, "" + player.BombAmmo, new Vector2(380 + 190, 713), Color.Black);
            Game1.spriteBatch.End();
             */
        }

        public void drawLivesPlayers()
        {
            int initialX = 30;
            int initialY = 600;
            int posX = initialX;
            int posY = initialY;
            int marginX = 200;
            int marginY = 20;
            foreach (KeyValuePair<String, Dictionary<String, Object>> aux in objects)
            {
                foreach (KeyValuePair<String, Object> i in aux.Value)
                {
                    Object obj = i.Value;
                    if (obj.Type == Object.TypeObject.player || obj.Type == Object.TypeObject.enemy)
                    {
                        Game1.spriteBatch.Begin();
                        Game1.spriteBatch.DrawString(Game1.font, obj.getStrType() + " " + obj.Id, new Vector2(posX, posY), Color.White);
                        posY += marginY;
                        Game1.spriteBatch.DrawString(Game1.font, "Lives: " + obj.Lives, new Vector2(posX, posY), Color.White);
                        posY += marginY;
                        Game1.spriteBatch.DrawString(Game1.font, "Level: " + obj.Level, new Vector2(posX, posY), Color.White);
                        posY += marginY;
                        Game1.spriteBatch.DrawString(Game1.font, "Gun ammo: " + obj.GunAmmo, new Vector2(posX, posY), Color.White);
                        posY += marginY;
                        Game1.spriteBatch.DrawString(Game1.font, "Bomb ammo: " + obj.BombAmmo, new Vector2(posX, posY), Color.White);
                        posY += marginY;
                        Game1.spriteBatch.DrawString(Game1.font, "kills: " + obj.Kills, new Vector2(posX, posY), Color.White);
                        Game1.spriteBatch.End();

                        posX += marginX;
                    }
                    posY = initialY;
                }
            }
        }


        public void drawColisions()
        {
            foreach (KeyValuePair<String, Dictionary<String, Object>> aux in objects)
            {
                foreach (KeyValuePair<String, Object> i in aux.Value)
                {
                    Object obj = i.Value;

                    Rectangle rectColision = obj.Colision;
                    
                    Game1.spriteBatch.Begin();
                    if (obj.Direction != null)
                    {
                        if (obj.Direction.getDirection() == "left" || obj.Direction.getDirection() == "right")
                            rectColision = obj.HorizontalColision;
                        if (obj.Direction.getDirection() == "up" || obj.Direction.getDirection() == "down")
                            rectColision = obj.VerticalColision;
                    }
                   
                    Rectangle rect = new Rectangle(obj.Position.X + rectColision.X, obj.Position.Y + rectColision.Y, rectColision.Width, rectColision.Height);
                    //Game1.spriteBatch.Draw(Game1.textColision, rect, Color.White);

                    Game1.spriteBatch.End();

                }
            }
       
            /*
                Dictionary<String, Object> aux = objects["colision"];
                foreach (KeyValuePair<String, Object> j in aux)
                {
                    Object colision = j.Value;
    
                       // Rectangle b = new Rectangle(colision.Position.X+16, colision.Position.Y+32, 32, 32);
                         //  Rectangle b = new Rectangle(colision.Position.X+15, colision.Position.Y+15,30, 25);
                    Rectangle b = new Rectangle(colision.Position.X, colision.Position.Y, 60, 55);
                        Game1.spriteBatch.Begin();

                        Game1.spriteBatch.Draw(Game1.textColision, b, Color.White);

                        Game1.spriteBatch.End();                    
                    
                }
                aux = objects["enemy"];
                foreach (KeyValuePair<String, Object> j in aux)
                {
                    Object colision = j.Value;

                    // Rectangle b = new Rectangle(colision.Position.X+16, colision.Position.Y+32, 32, 32);
                    //  Rectangle b = new Rectangle(colision.Position.X+15, colision.Position.Y+15,30, 25);
                    Rectangle b = new Rectangle(colision.Position.X, colision.Position.Y, 64, 55);
                    Game1.spriteBatch.Begin();

                    Game1.spriteBatch.Draw(Game1.textColision, b, Color.White);

                    Game1.spriteBatch.End();

                }
                aux = objects["player"];
                foreach (KeyValuePair<String, Object> j in aux)
                {
                    Object colision = j.Value;

                    // Rectangle b = new Rectangle(colision.Position.X+16, colision.Position.Y+32, 32, 32);
                    //  Rectangle b = new Rectangle(colision.Position.X+15, colision.Position.Y+15,30, 25);
                    Rectangle b;
                    if(colision.Direction.getDirection() == "left" || colision.Direction.getDirection() == "right")
                        b  = new Rectangle(colision.Position.X + 16, colision.Position.Y + 32, 32, 32);
                    else
                        b = new Rectangle(colision.Position.X + 26, colision.Position.Y + 32, 10, 32);
                    Game1.spriteBatch.Begin();

                    Game1.spriteBatch.Draw(Game1.textColision, b, Color.White);

                    Game1.spriteBatch.End();

                }
                aux = objects["projectile"];
                foreach (KeyValuePair<String, Object> j in aux)
                {
                    Object colision = j.Value;

                    // Rectangle b = new Rectangle(colision.Position.X+16, colision.Position.Y+32, 32, 32);
                    //  Rectangle b = new Rectangle(colision.Position.X+15, colision.Position.Y+15,30, 25);
                    Rectangle b;
                    if (colision.Direction.getDirection() == "left" || colision.Direction.getDirection() == "right")
                       b = new Rectangle(colision.Position.X + 10, colision.Position.Y + 22, 55, 16);
                    else
                       b = new Rectangle(colision.Position.X + 26, colision.Position.Y + 10, 10, 48);
                    Game1.spriteBatch.Begin();

                    Game1.spriteBatch.Draw(Game1.textColision, b, Color.White);

                    Game1.spriteBatch.End();

                }*/
        }

        public Object checkColisionProjectile(Object obj, ArrayList type, ArrayList ignoreObjects)
        {
            /*
            ArrayList characters = getCharacters();
            for (int i = 0; i < characters.Count; i++)
            {
                Object colision = (Object)characters[i];
                Rectangle rectColision = colision.Colision;
                Rectangle rectObject = obj.Colision;
                if (ignoreObjects.Contains(colision.Id) == false)
                {
                    if (obj.Direction != null)
                    {
                        if (obj.Direction.getDirection() == "left" || obj.Direction.getDirection() == "right")
                            rectObject = obj.HorizontalColision;
                        if (obj.Direction.getDirection() == "up" || obj.Direction.getDirection() == "down")
                            rectObject = obj.VerticalColision;
                    }
                    Rectangle a = new Rectangle(obj.Position.X + rectObject.X, obj.Position.Y + rectObject.Y, rectObject.Width, rectObject.Height);
                    Rectangle b = new Rectangle(colision.Position.X + rectColision.X, colision.Position.Y + rectColision.Y, rectColision.Width, rectColision.Height);
                    if (Game1.modeDebug)
                    {
                        Game1.spriteBatch.Begin();
                        Game1.spriteBatch.Draw(Game1.textColision, a, Color.White);
                        Game1.spriteBatch.Draw(Game1.textColision, b, Color.White);
                        Game1.spriteBatch.End();
                    }
                    if (rectangleColission(a, b))
                        return colision;
                }
            }
            return null;*/

            for (int i = 0; i < type.Count; i++)
            {
                Dictionary<String, Object> aux = objects[(String)type[i]];
                foreach (KeyValuePair<String, Object> j in aux)
                {
                    Object colision = j.Value;

                    Rectangle rectColision = colision.Colision;
                    Rectangle rectObject = obj.Colision;
                    if (ignoreObjects.Contains(colision.Id) == false)
                    {
                        if (obj.Direction != null)
                        {
                            if (obj.Direction.getDirection() == "left" || obj.Direction.getDirection() == "right")
                                rectObject = obj.HorizontalColision;
                            if (obj.Direction.getDirection() == "up" || obj.Direction.getDirection() == "down")
                                rectObject = obj.VerticalColision;
                        }
                        Rectangle a = new Rectangle(obj.Position.X + rectObject.X, obj.Position.Y + rectObject.Y, rectObject.Width, rectObject.Height);
                        Rectangle b = new Rectangle(colision.Position.X + rectColision.X, colision.Position.Y + rectColision.Y, rectColision.Width, rectColision.Height);
                        if (Game1.modeDebug)
                        {
                            Game1.spriteBatch.Begin();
                            Game1.spriteBatch.Draw(Game1.textColision, a, Color.White);
                            Game1.spriteBatch.Draw(Game1.textColision, b, Color.White);
                            Game1.spriteBatch.End();
                        }
                        if (rectangleColission(a, b))
                        {
                            // Check colision with wall
                            Object aux1 = checkColision(obj, "missile", ignoreObjects);
                            if (aux1 != null)
                                return aux1;
                            return colision;
                        }
                    }
                }
            }
            return checkColision(obj, "missile", ignoreObjects); ;
        }

        public Object checkColision(Object obj, String typeColision, ArrayList ignoreObjects)
        {
            Dictionary<String, Object> aux = objects["colision"];
            foreach (KeyValuePair<String, Object> j in aux)
            {
                Colision colision = (Colision)j.Value;
                if (typeColision.Contains(colision.TypeColision))
                {
                    Rectangle rectColision = colision.Colision;
                    Rectangle rectObject = obj.Colision;
                    if (obj.Direction != null)
                    {
                        if (obj.Direction.getDirection() == "left" || obj.Direction.getDirection() == "right")
                            rectObject = obj.HorizontalColision;
                        if (obj.Direction.getDirection() == "up" || obj.Direction.getDirection() == "down")
                            rectObject = obj.VerticalColision;
                    }
                    Rectangle a = new Rectangle(obj.Position.X + rectObject.X, obj.Position.Y + rectObject.Y, rectObject.Width, rectObject.Height);
                    Rectangle b = new Rectangle(colision.Position.X + rectColision.X, colision.Position.Y + rectColision.Y, rectColision.Width, rectColision.Height);
                    if (Game1.modeDebug)
                    {
                        Game1.spriteBatch.Begin();
                        Game1.spriteBatch.Draw(Game1.textColision, a, Color.White);
                        Game1.spriteBatch.Draw(Game1.textColision, b, Color.White);
                        Game1.spriteBatch.End();
                    }
                    if (rectangleColission(a, b))
                        return colision;
                }

            }
            return null;

            /*
            for (int i = 0; i < type.Count; i++)
            {
                Dictionary<String, Object> aux = objects[(String)type[i]];
                foreach (KeyValuePair<String, Object> j in aux)
                {
                    Object colision = j.Value;
                    if(ignoreObjects.Contains(colision.Id) == false)
                    {

                        Rectangle rect = obj.Colision;

                        Boolean ignore = false;
                        if (colision.Type == Object.TypeObject.colision)
                        {
                            Colision col = (Colision)colision;
                            if (col.Ignore == "projectile" && obj.Type == Object.TypeObject.projectile)
                                ignore = true;
                        }

                        if (ignore == false)
                        {
                            if (obj.Direction != null)
                            {
                                if (obj.Direction.getDirection() == "left" || obj.Direction.getDirection() == "right")
                                    rect = obj.HorizontalColision;
                                if (obj.Direction.getDirection() == "up" || obj.Direction.getDirection() == "down")
                                    rect = obj.VerticalColision;
                            }

                            Rectangle a = new Rectangle(obj.Position.X + rect.X, obj.Position.Y + rect.Y, rect.Width, rect.Height);
                            Rectangle b = new Rectangle(colision.Position.X + colision.Colision.X, colision.Position.Y + colision.Colision.Y, colision.Colision.Width, colision.Colision.Height);
                            if (Game1.modeDebug)
                            {
                                Game1.spriteBatch.Begin();
                                Game1.spriteBatch.Draw(Game1.textColision, a, Color.White);
                                Game1.spriteBatch.Draw(Game1.textColision, b, Color.White);
                                Game1.spriteBatch.End();
                            }
                            if (rectangleColission(a, b))
                                return colision;
                        }
                    }
                }
            }
            return null;  */
        }

        public void reset()
        {
            objects = new Dictionary<string, Dictionary<string, Object>>();
            objects.Add("player", new Dictionary<string, Object>());
            objects.Add("colision", new Dictionary<string, Object>());
            objects.Add("enemy", new Dictionary<string, Object>());
            objects.Add("bomb", new Dictionary<string, Object>());
            objects.Add("projectile", new Dictionary<string, Object>());
            objects.Add("explosion", new Dictionary<string, Object>());
            objects.Add("items", new Dictionary<string, Object>());
            objects.Add("wall", new Dictionary<string, Object>());
            countObjects = 0;
            aiInterface.reset();
        }

        public Boolean rectangleColission(Rectangle a, Rectangle b)
        {
            if ((a.X < b.X + b.Width) && (b.X < a.X + a.Width) && (a.Y < b.Y + b.Height))
            {
                return b.Y < a.Y + a.Height;
            }
            return false;
        } 


        public void receivedAttack(Object victim, int force)
        {
            int rowVictim = World.getNumRow(victim.Position.Y);
            int columnVictim = World.getNumColumn(victim.Position.X);
            switch (victim.Type)
            {
                case Object.TypeObject.colision:
                    {
                        Colision colision = (Colision)victim;
                        if (colision.Destroyable == true)
                        {
                            // Create item
                            //Random r = new Random(DateTime.Now.Millisecond);
                            //int number = r.Next(0, 2);
                            //System.Console.WriteLine(number);
                            //if (number == 1)
                                createItem(rowVictim, columnVictim);
                            gameInfo.removeObject(victim.Id, victim.Type);
                        }
                        break;
                    }
            }

        }

        public Boolean detectBox(Enemy enemy)
        {
            ArrayList cells = getVision(enemy,enemy.Level);
     
            for (int i = 0; i < cells.Count; i++)
            {
                Cell cell = (Cell)cells[i];
                // Check if there are a box
                Object obj = world.get(cell.Row,cell.Column).Obj;
                if(obj != null && obj.Type == Object.TypeObject.colision)
                {
                    Colision colision = (Colision)obj;
                    if (colision.Life > 0)
                        return true;
                }
            }
            return false;
        }

        public Object detectEnemy(Enemy enemy)
        {
            //System.Console.WriteLine(enemy.Name);
            // Get cells vision enemy
            ArrayList cells = getVision(enemy,maxVision);
            // Check colision with a enemy in these cells
            for (int i = 0; i < cells.Count; i++)
            {
                Cell cell = (Cell)cells[i];
                Rectangle rectCell = new Rectangle(cell.getRealX(), cell.getRealY(), world.Size, world.Size-25);
                ArrayList characters = getCharacters();
                for (int j = 0; j < characters.Count; j++)
                {
                    Object character = (Object)characters[j];
                    // Ignore members of the same team and the character AND if the character is blinking
                    if (character != null && character.Id != enemy.Id && character.Blinking == false)
                    {
                        if (enemy.Team != character.Team || enemy.FireFriendly == true)
                        {
                            Rectangle rectEnemy = new Rectangle(character.Position.X + character.Colision.X, character.Position.Y + character.Colision.Y, character.Colision.Width, character.Colision.Height);
                            if (rectangleColission(rectCell, rectEnemy))
                            {
                                // Colision
                                //System.Console.WriteLine(enemy.Name + "colision with" + character.Name);
                                return character;
                            }
                        }
                    }
                }
            }
            return null;
        }


        public Cell detectPlayer(Enemy enemy)
        {
            ArrayList cells = getVision(enemy,maxVision);

            for (int i = 0; i < cells.Count; i++)
            {
                Cell cell = (Cell)cells[i];
                Rectangle a = new Rectangle(cell.getRealX(), cell.getRealY(), 64, 64);

                Dictionary<String, Object> aux = objects["player"];
                foreach (KeyValuePair<String, Object> item in aux)
                {
                    Object player = item.Value;
                    Rectangle b = new Rectangle(player.Position.X + player.Colision.X, player.Position.Y + player.Colision.Y, player.Colision.Width, player.Colision.Height);
                    if (rectangleColission(a, b))
                        return cell;
                }


            }

            return null;
        }

        public ArrayList getEmptyCells(Object obj, int rows, int columns)
        {
            ArrayList cells = new ArrayList();
            int initialRow = World.getNumRow(obj.Position.Y)-rows;
            int initialColumn = World.getNumColumn(obj.Position.X)-columns;
            for (int i = initialRow; i <= initialRow + rows * 2 && i < world.Rows; i++)
            {
                for (int j = initialColumn; j <= initialColumn + columns * 2 && j < world.Columns; j++)
                {
                    if (i >= 0 && j >= 0)
                    {
                        Cell cell = World.get(i, j);
                        if (cell.Obj == null)
                            cells.Add(new Cell(i, j, World.Size));
                    }
                }
            }
            /*
            switch (obj.Direction.getDirection())
            {
                case "down":
                    {

                        break;
                    }
                case "left":
                    {
                        for (int i = initialRow; i <= initialRow + rows * 2 && i < world.Rows; i++)
                        {
                            for (int j = initialColumn; j <= initialColumn + columns * 2 && j < world.Columns; j++)
                            {
                                if (i >= 0 && j >= 0)
                                {
                                    Cell cell = World.get(i, j);
                                    if (cell.Obj == null)
                                        cells.Add(new Cell(i, j, World.Size));
                                }
                            }
                        }
                        break;
                    }
            }*/
            return cells;
        }

        public ArrayList getVision(Object obj, int maxDistance)
        {
            ArrayList vision = new ArrayList();

            int row = World.getNumRow(obj.Position.Y);
            int column = World.getNumColumn(obj.Position.X);
            int directionX = obj.Direction.X;
            int directionY = obj.Direction.Y;
            switch (obj.Direction.getDirection())
            {
                case "down":
                    {
                        for (int i = row + 1; i <= row + maxDistance && i < world.Rows; i++)
                        {
                            Cell cell = world.get(i, column);
                            if (cell.Obj != null && cell.Obj.Type == Object.TypeObject.colision)
                            {
                                Colision colision = (Colision)cell.Obj;
                                if (colision.Life == 0)
                                    break;
                            }
                            vision.Add(new Cell(i, column, World.Size));
                        }
                        break;
                    }
                    
                case "up":
                    {
                        for (int i = row - 1; i >= row - maxDistance && i >= 0; i--)
                        {
                            Cell cell = world.get(i, column);
                            if (cell.Obj != null && cell.Obj.Type == Object.TypeObject.colision)
                            {
                                Colision colision = (Colision)cell.Obj;
                                if (colision.Life == 0)
                                    break;
                            }
                            vision.Add(new Cell(i, column, World.Size));
            
                        }
                        break;
                    }
                case "left":
                    {
                        for (int j = column - 1; j >= column - maxDistance && j >= 0; j--)
                        {
                            Cell cell = world.get(row, j);
                            if (cell.Obj != null && cell.Obj.Type == Object.TypeObject.colision)
                            {
                                Colision colision = (Colision)cell.Obj;
                                if(colision.Life == 0)
                                    break;
                            }
                            vision.Add(new Cell(row-1, j, World.Size));
                            
                        }
                        break;
                    }
                case "right":
                    {
                        for (int j = column + 1; j <= column + maxDistance && j < world.Columns; j++)
                        {
                            Cell cell = world.get(row, j);
                            if (cell.Obj != null && cell.Obj.Type == Object.TypeObject.colision)
                            {
                                Colision colision = (Colision)cell.Obj;
                                if (colision.Life == 0)
                                    break;
                            }
                            vision.Add(new Cell(row-1, j, World.Size));
                            
                        }
                        break;
                    }
                     
            }
            return vision;

        }
        public void removeObject(String id)
        {
            foreach (KeyValuePair<String, Dictionary<String, Object>> aux in objects)
            {
                foreach (KeyValuePair<String, Object> aux2 in aux.Value)
                {
                    Object obj = aux2.Value;
                    if (obj.Id == id)
                    {
                        aux.Value.Remove(id);
                        aiInterface.deleteObject(id);
                        for (int i = 0; i < world.Rows; i++)
                        {
                            for (int j = 0; j < world.Columns; j++)
                            {
                                Cell cell = world.get(i, j);
                                if (cell.Obj != null && cell.Obj.Id == id)
                                    cell.Obj = null;
                            }
                        }
                        break;
                    }
                }
            }
            /*
            foreach (KeyValuePair<String, Dictionary<String, Object>> aux in objects)
            {
                aux.Value.Remove(id);
                aiInterface.deleteObject(id);
                // Check if is in the world
                for (int i = 0; i < world.Rows; i++)
                {
                    for (int j = 0; j < world.Columns; j++)
                    {
                        Cell cell = world.get(i, j);
                        if (cell.Obj != null && cell.Obj.Id == id)
                            cell.Obj = null;
                    }
                }
            } */
        }
        public void checkItem(Object character)
        {
            Dictionary<String, Object> aux = objects["items"];
            foreach (KeyValuePair<String, Object> i in aux)
            {
                Object item = i.Value;

                Rectangle a = new Rectangle(character.Position.X, character.Position.Y, 40, 40);
                Rectangle b = new Rectangle(item.Position.X, item.Position.Y, 40, 40);
                if (rectangleColission(a, b))
                {
                    // Set the item
                    character.GunAmmo += item.GunAmmo;
                    character.BombAmmo += item.BombAmmo;
                    if(character.Level < 5)
                    character.Level += item.Level;

                    // Remove object
                    removeObject(item.Id);

                    break;
                }
            }
        }

        public void drawEmptyCellEnemies()
        {
            Dictionary<String, Object> aux = objects["enemy"];
            foreach (KeyValuePair<String, Object> i in aux)
            {
                Object obj = i.Value;
                ArrayList cells = getEmptyCells(obj,2,2);
                for (int k = 0; k < cells.Count; k++)
                {
                    Cell cell = (Cell)cells[k];
                    Game1.spriteBatch.Begin();
                    Game1.spriteBatch.Draw(Game1.textCellVision, new Rectangle(cell.Column * world.Size, cell.Row * world.Size, Game1.textCellVision.Bounds.Width, Game1.textCellVision.Bounds.Height), Color.White);
                    Game1.spriteBatch.End();
                }
            }
        }

        public void drawCellVisionEnemies()
        {
            Dictionary<String, Object> aux = objects["enemy"];
            foreach (KeyValuePair<String, Object> i in aux)
            {
                Object obj = i.Value;
                ArrayList cells = getVision(obj,maxVision);
                for (int k = 0; k < cells.Count; k++)
                {
                    Cell cell = (Cell)cells[k];
                    Game1.spriteBatch.Begin();
                    Game1.spriteBatch.Draw(Game1.textCellVision, new Rectangle(cell.Column * world.Size, cell.Row * world.Size, Game1.textCellVision.Bounds.Width, Game1.textCellVision.Bounds.Height), Color.White);
                    Game1.spriteBatch.End();
                }
            }


        }

        public Dictionary<String, Object> getObjects(String type)
        {
            return objects[type];
        }

        public Cell detectItem(Object obj)
        {
            Cell cell = null;
            
            Dictionary<String, Object> aux = objects["items"];
            foreach (KeyValuePair<String, Object> i in aux)
            {
                Object item = i.Value;
                double distance = Math.Sqrt(Math.Pow(obj.Position.X - item.Position.X, 2) + Math.Pow(obj.Position.Y - item.Position.Y, 2));
                if (distance < 400)
                {
                    // Check if is possible take this item (pathfinder)
                    int row = world.getNumRow(item.Position.Y);
                    int column = world.getNumColumn(item.Position.X);
                    if(existsRoute(obj,row,column))
                        return world.get(row, column);
                }
            }
            return cell;
        }

        public ArrayList moveRandomEnemy(Object obj, int maxDistance)
        {
            // Get empty cells near of the object
            ArrayList emtpyCells = getEmptyCells(obj, maxDistance, maxDistance);
            //if (emtpyCells.Count <= 2)
            //    Console.ReadKey();
            ArrayList route = null;
            while (route == null)
            {
                
                // Select random cell
                Random r = new Random(DateTime.Now.Millisecond);
                int numCell = r.Next(0, emtpyCells.Count - 1);
                Cell cell = (Cell)emtpyCells[numCell];
                emtpyCells.Remove(numCell);
                // Move enemy
                route = moveEnemy(obj, cell.Row, cell.Column);
                //System.Console.WriteLine("Route to " + cell.Row + "," + cell.Column + ": " + route.Count);
            }
            //System.Console.ReadKey();
            return route;
        }


        public Boolean existsRoute(Object obj, int row, int column)
        {
            Boolean exists = false;

            byte[,] matrix = new byte[32, 32];

            // Inicitalize matrix
            for (int i = 0; i < world.Rows; i++)
            {
                for (int j = 0; j < world.Columns; j++)
                {
                    Cell cell = world.get(i, j);
                    if (cell.Obj != null)
                    {
                        if (cell.Obj.Type == Object.TypeObject.player)
                            matrix[i, j] = 1;
                        else
                            matrix[i, j] = 0;
                    }
                    else
                    {
                        matrix[i, j] = 1;
                    }
                }
            }

            PathFinderFast pathfinder = new PathFinderFast(matrix);
            pathfinder.Diagonals = false;
            pathfinder.Formula = HeuristicFormula.Manhattan;
            pathfinder.HeuristicEstimate = 1;
            int rowEnemy = gameInfo.World.getNumRow(obj.Position.Y);
            int columnEnemy = gameInfo.World.getNumRow(obj.Position.X);
            List<PathFinderNode> nodes = pathfinder.FindPath(new Point(rowEnemy, columnEnemy), new Point(row, column));

            if (nodes != null)
               exists = true;
  
            return exists;
        }

        public ArrayList moveEnemy(Object obj, int row, int column)
        {
            byte[,] matrix = new byte[32, 32];

            // Inicitalize matrix
            for (int i = 0; i < world.Rows; i++)
            {
                for (int j = 0; j < world.Columns; j++)
                {
                    Cell cell = world.get(i, j);
                    if (cell.Obj != null)
                    {
                        if (cell.Obj.Type == Object.TypeObject.player)
                            matrix[i, j] = 1;
                        else
                            matrix[i, j] = 0;
                    }
                    else
                    {
                        matrix[i, j] = 1;
                    }

                }

            }

            PathFinderFast pathfinder = new PathFinderFast(matrix);
            pathfinder.Diagonals = false;
            pathfinder.Formula = HeuristicFormula.Manhattan;
            pathfinder.HeuristicEstimate = 1;
            int rowEnemy = gameInfo.World.getNumRow(obj.Position.Y);
            int columnEnemy = gameInfo.World.getNumRow(obj.Position.X);
            List<PathFinderNode> nodes = pathfinder.FindPath(new Point(rowEnemy, columnEnemy), new Point(row, column));
            ArrayList cells = new ArrayList();

            if (nodes == null)
            {
                System.Console.WriteLine("error pathfinder: " + row + "," + column);
                System.Console.WriteLine(world);
            }
            else
            {
                if (nodes.Count > 1)
                {
                    for (int i = nodes.Count - 2; i >= 0; i--)
                    {
                        PathFinderNode node = nodes[i];
                        matrix[node.X, node.Y] = 5;
                        cells.Add(new Cell(node.X, node.Y, world.Size));
                    }
                    obj.Route = cells;
                    //obj.IsMoving = true;
                }
            }

            // Check direction
            if(cells.Count > 0)
            {
                Cell nextCell = (Cell)obj.Route[0];
                int dx = nextCell.Column - columnEnemy;
                int dy = nextCell.Row - rowEnemy;
                obj.Direction = new Direction2D(dx, dy);
            }

            return cells;
        }
        public void stop(Object obj)
        {
            EventEmitter.getInstance().registerMessage(0, obj.Id, obj.Id, Message.MessageType.msg_stopApproximate);
        }

        public void move(Object obj, int row, int column, Direction2D direction)
        {
            // Move player
            /*
            if (obj.Direction.getDirection() == "right" && direction.getDirection() == "up" && obj.Movement == null)
            {
                System.Console.WriteLine(obj.Direction.getDirection());
                EventEmitter.getInstance().registerMessage(0, obj.Id, obj.Id, Message.MessageType.msg_stop);
            }
            else
            {
                EventEmitter.getInstance().registerMessage(0, obj.Id, obj.Id, Message.MessageType.msg_move);
                obj.Movement = new Position2D(column * world.Size, row * world.Size);
                obj.Direction = direction;
                obj.changeAnimation("move_" + obj.Direction.getDirection());
            }*/

            /*
            if (obj.Direction.X * direction.X != 0 || obj.Direction.Y * direction.Y != 0)
            {
                EventEmitter.getInstance().registerMessage(0, obj.Id, obj.Id, Message.MessageType.msg_move);
                obj.Movement = new Position2D(column * world.Size, row * world.Size);
                obj.Direction = direction;
                obj.changeAnimation("move_" + obj.Direction.getDirection());

            }
            */
            

            //if (aiObject.StateMachine.CurrentState.Name == "StopState")
            //{
            // Check if is possible
    
                //if (player.Moving == false || obj.Direction.X * direction.X != 0 || obj.Direction.Y * direction.Y != 0)
                //{
                    EventEmitter.getInstance().registerMessage(0, obj.Id, obj.Id, Message.MessageType.msg_move);
                    obj.Movement = new Position2D(column * world.Size, row * world.Size);
                    obj.Direction = direction;
                    obj.changeAnimation("move_" + obj.Direction.getDirection());
                //}
                //else
                //{
                //    if (obj.Direction.getDirection() != direction.getDirection())
                  //      gameInfo.stop(player);
                //}

            //}

            /*
            if (obj.Type == Object.TypeObject.powerUp)
                obj.draw();

            // Check if is a enemy
            if (obj.Type == Object.TypeObject.enemy)
            {
                AIObject aiObject = EventManager.getInstance().getAIObject(obj.Id);

                if (aiObject.StateMachine.CurrentState.Name == "FollowState")
                {

                    obj.draw();
                }
            }*/
            // Check if is possible
            //Cell cell = world.get(row, column);
            //if (cell.Obj == null)
            //{
              //  if (obj.Movement == null || obj.Direction.getDirection() == direction.getDirection())
               // {
            /*
                System.Console.WriteLine("moving");
                    obj.Movement = new Position2D(column * world.Size, row * world.Size);
                    obj.Direction = direction;
                    obj.changeAnimation("move_" + obj.Direction.getDirection());

                    int aux_row = world.getNumRow(obj.Position.Y);
                    int aux_column = world.getNumColumn(obj.Position.X);
                    Cell aux_cell = world.get(aux_row, aux_column);
                    aux_cell.Obj = null;
                    aux_cell = world.get(row, column);
                    aux_cell.Obj = obj;
                    System.Console.WriteLine(world);
             */
             //   }
        /*    
        }
            else
            {
                System.Console.WriteLine("moving");
                obj.Direction = direction;
            } */
            /*
            int rowEnemy = gameInfo.World.getNumRow(this.Position.Y);
            int columnEnemy = gameInfo.World.getNumColumn(this.Position.X);
            int previousRow = gameInfo.World.getNumRow(this.PreviousPosition.Y);
            int previousColumn = gameInfo.World.getNumColumn(this.PreviousPosition.X);
            if (rowEnemy != previousRow || columnEnemy != previousColumn)
            {
                Cell cell = gameInfo.World.get(previousRow, previousColumn);
                cell.Obj = null;
                cell = gameInfo.World.get(rowEnemy, columnEnemy);
                cell.Obj = this;
            }*/
        }
    
        public void moveLeft(Object obj)
        {
            
            int row = world.getNumRow(obj.Position.Y);
            int column = world.getNumColumn(obj.Position.X) - 1;
            //if (column >= 0)
            //{
                 
                // Move
                //if (obj.Movement == null)
                //player.changeAnimation("left");
                move(obj, row, column, new Direction2D(-1, 0));
             
            //}
        }

        public void moveRight(Object obj)
        {
            int row = world.getNumRow(obj.Position.Y);
            int column = world.getNumColumn(obj.Position.X)+1;
            if (column < world.Columns)
            {
                // Move
               // if (obj.Movement == null)
                //player.changeAnimation("right");
                move(obj, row, column, new Direction2D(1, 0));

            }
        }

        public void moveUp(Object obj)
        {
            int row = world.getNumRow(obj.Position.Y)-1;
            int column = world.getNumColumn(obj.Position.X);
            if (row >= 0)
            {
                // Move
                //if (obj.Movement == null)
                //player.changeAnimation("back");
                move(obj, row, column, new Direction2D(0, -1));
            }
        }

        public void moveDown(Object obj)
        {
            int row = world.getNumRow(obj.Position.Y)+1;
            int column = world.getNumColumn(obj.Position.X);
            if (row < world.Rows)
            {
                // Move
               // if (obj.Movement == null)
                //player.changeAnimation("front");
                move(obj, row, column, new Direction2D(0, 1));
            }
        }

        //public void moveObject(

        public Object getPlayer(String name)
        {
            Dictionary<String, Object> aux = objects["player"];
            foreach (KeyValuePair<String, Object> item in aux)
            {
                Object player = item.Value;
                if (player.Name == name)
                    return player;
            }
            return null;
        }

        public static GameInfo getInstance()
        {
            if (gameInfo == null)
                gameInfo = new GameInfo();
            return gameInfo;
        }

        public World World
        {
            get { return world; }
            set { world = value; }
        }
        public int MinMission
        {
            get { return minMission; }
            set { minMission = value; }
        }
        public int Level
        {
            get { return level; }
            set { level = value; }
        }
    }
}
